/* Configuration */
local ScoreboardAlpha = 0
local ScoreboardHeight = 0
local ScoreboardShowSpeed = 5
local TitleTexture = surface.GetTextureID("vgui/title")
local BgTexture = surface.GetTextureID("vgui/bg-scoreboard")
local ShowBoard = false

/*---------------------------------------------------------
   Name: gamemode:ScoreboardShow( )
   Desc: Sets the scoreboard to visible
---------------------------------------------------------*/
function GM:ScoreboardShow()

	/* Default */
	GAMEMODE.ShowScoreBoard = true
	if not ShowBoard then ShowBoard = true
	else ShowBoard = false end
end

/*---------------------------------------------------------
   Name: gamemode:ScoreboardHide( )
   Desc: Hides the scoreboard
---------------------------------------------------------*/
function GM:ScoreboardHide()

	/* Default */
	GAMEMODE.ShowScoreBoard = false
	-- ShowBoard = false
end

function GM:HUDDrawScoreBoard()

	/* ************************************************************ */
	/* **NOTHING TO DO********************************************* */
	/* ************************************************************ */
	
	/* Fully hidden */
	if not ShowBoard and (ScoreboardAlpha <= 0 and ScoreboardHeight <= 0) then return end
	
	/* ************************************************************ */
	/* **CALCULATE HEIGHT & ALPHA********************************** */
	/* ************************************************************ */
	
	/* Increase alpha */
	if ShowBoard then ScoreboardAlpha = math.Round(math.Clamp(ScoreboardAlpha + ScoreboardShowSpeed, 0, 255), 1)
	
	/* Decrease alpha */
	else ScoreboardAlpha = math.Round(math.Clamp(ScoreboardAlpha - ScoreboardShowSpeed, 0, 255), 1) end
	
	/* Increase height */
	if ShowBoard then ScoreboardHeight = math.Round(math.Clamp(ScoreboardHeight + ScoreboardShowSpeed / 300, 0, 1), 3)
	
	/* Decrease height */
	else ScoreboardHeight = math.Round(math.Clamp(ScoreboardHeight - ScoreboardShowSpeed / 300, 0, 1), 3) end
	
	/* ************************************************************ */
	/* **INFORMATION*********************************************** */
	/* ************************************************************ */
	
	/* Get team & player info */
	local scoreboardInfo	= self:GetTeamScoreInfo()			-- self:GetFakeTeamScoreInfo(4, 5)
	local numPlayers		= table.Count(player.GetAll())		-- 20
	
	/* ************************************************************ */
	/* **CALCULATIONS********************************************** */
	/* ************************************************************ */
	
	/* Frame configuration */
	local globalRatio	= 5
	local boardRatio	= 15 / globalRatio
	local titleRatio	= globalRatio * 2
	local playerRatio	= globalRatio * 8
	local teamRatio		= globalRatio * 8
	local headerRatio	= globalRatio * 8
	local offsetX		= ScrW() / boardRatio
	local titleHeight	= ScoreboardHeight * (ScrH() / titleRatio)
	local maxTitleHeight= ScrH() / titleRatio
	local playerHeight	= ScoreboardHeight * (ScrH() / playerRatio)
	local teamHeight	= ScoreboardHeight * (ScrH() / teamRatio)
	local headerHeight	= ScoreboardHeight * (ScrH() / headerRatio)
	local boardWidth	= ScrW() - offsetX * 2
	local boardHeight	= numPlayers * playerHeight + (table.Count(scoreboardInfo)) * teamHeight + headerHeight
	local totalHeight	= titleHeight + boardHeight
	local offsetY		= (ScrH() / 2) - (totalHeight / 2)
	local boardOffsetY	= offsetY + titleHeight
	local textOffsetX	= globalRatio + 2
	local textOffsetY	= globalRatio + 2
	local columnWidth	= boardWidth / 5
	
	/* ************************************************************ */
	/* **SOUNDS**************************************************** */
	/* ************************************************************ */
	
	/* Opening sound*/
	if ShowBoard and ScoreboardAlpha < 255 then
		surface.PlaySound("ambient/levels/citadel/pod_open1.wav")
		
	/* Closing sound */
	elseif not ShowBoard and ScoreboardAlpha > 0 then
		surface.PlaySound("ambient/levels/citadel/pod_close1.wav")
	end
	
	/* ************************************************************ */
	/* **DRAWINGS************************************************** */
	/* ************************************************************ */
	
	/* Draw title */
	surface.SetDrawColor( 255, 255, 255, math.min(ScoreboardAlpha, 200) )
	surface.SetTexture(TitleTexture)
	surface.DrawTexturedRectUV(offsetX, offsetY, boardWidth, titleHeight, boardWidth, maxTitleHeight)

	/* Draw the main background */
	surface.SetDrawColor( 255, 255, 255, math.min(ScoreboardAlpha, 200) )
	surface.SetTexture(BgTexture)
	surface.DrawTexturedRect(offsetX - 10, boardOffsetY, boardWidth + 20, boardHeight + 10)
	
	/* Header colors */
	surface.SetDrawColor( 200, 10, 10, math.min(ScoreboardAlpha, 100) )
	surface.SetTextColor( 255, 255, 255, math.min(ScoreboardAlpha, 200) )
	
	/* Draw header background */
	surface.DrawRect( offsetX, boardOffsetY, boardWidth, playerHeight )
	
	/* Draw header line */
	surface.SetFont( "ScoreboardText" )
	surface.SetTextPos( offsetX + textOffsetX, boardOffsetY + textOffsetY )
	surface.DrawText( "Player name" )
	surface.SetTextPos( offsetX + textOffsetX + boardWidth - 3 * columnWidth, boardOffsetY + textOffsetY )
	surface.DrawText( "Kills" )
	surface.SetTextPos( offsetX + textOffsetX + boardWidth - 2 * columnWidth, boardOffsetY + textOffsetY )
	surface.DrawText( "Deaths" )
	surface.SetTextPos( offsetX + textOffsetX + boardWidth - 1 * columnWidth, boardOffsetY + textOffsetY )
	surface.DrawText( "Ping" )
	
	/* Draw player info */
	local totalOffsetY = boardOffsetY + headerHeight
	for teamID, teamInfo in pairs(scoreboardInfo) do
		
		/* Calculate gray */
		local gray = 255 - (0.3 * teamInfo.Color.r + 0.59 * teamInfo.Color.g + 0.11 * teamInfo.Color.b)
		if gray > 100 and gray < 150 then gray = gray + 75 end
		
		/* Team colors */
		surface.SetDrawColor( teamInfo.Color.r, teamInfo.Color.g, teamInfo.Color.b, math.min(ScoreboardAlpha, 100) )
		surface.SetTextColor( gray, gray, gray, math.min(ScoreboardAlpha, 200) )
		
		/* Draw team background */
		surface.DrawRect( offsetX, totalOffsetY, boardWidth, playerHeight )
		
		/* Draw team text */
		surface.SetTextPos( offsetX + textOffsetX, totalOffsetY + textOffsetY )
		surface.DrawText( teamInfo.TeamName )
		
		/* Update offset */
		totalOffsetY = totalOffsetY + teamHeight
		
		/* Players of the team */
		for playerID, playerInfo in pairs(teamInfo.Players) do
			
			/* Colors */
			if playerID % 2 == 0 then
				surface.SetDrawColor( 75, 75, 75, math.min(ScoreboardAlpha, 100) )
				surface.SetTextColor( 150, 150, 150, math.min(ScoreboardAlpha, 200) )
			else
				surface.SetDrawColor( 130, 130, 130, math.min(ScoreboardAlpha, 100) )
				surface.SetTextColor( 25, 25, 25, math.min(ScoreboardAlpha, 200) )
			end
			
			/* Draw player background */
			surface.DrawRect( offsetX, totalOffsetY, boardWidth, playerHeight )
			
			/* Draw player text */
			surface.SetFont( "ScoreboardText" )
			surface.SetTextPos( offsetX + textOffsetX, totalOffsetY + textOffsetY )
			surface.DrawText( playerInfo.Name )
			surface.SetTextPos( offsetX + textOffsetX + boardWidth - 3 * columnWidth, totalOffsetY + textOffsetY )
			surface.DrawText( playerInfo.Frags )
			surface.SetTextPos( offsetX + textOffsetX + boardWidth - 2 * columnWidth, totalOffsetY + textOffsetY )
			surface.DrawText( playerInfo.Deaths )
			surface.SetTextPos( offsetX + textOffsetX + boardWidth - 1 * columnWidth, totalOffsetY + textOffsetY )
			surface.DrawText( playerInfo.Ping )
			
			/* Update offset */
			totalOffsetY = totalOffsetY + playerHeight
		end
	end
end

// TODO: CLEAN THIS CODE
/* This is from base */

function GM:GetTeamScoreInfo()
	local TeamInfo = {}
	
	for id,pl in pairs( player.GetAll() ) do
	
		local _team = pl:Team()
		local _frags = pl:Frags()
		local _deaths = pl:Deaths()
		local _ping = pl:Ping()
		
		if (not TeamInfo[_team]) then
			TeamInfo[_team] = {}
			TeamInfo[_team].TeamName = team.GetName( _team )
			TeamInfo[_team].Color = team.GetColor( _team )
			TeamInfo[_team].Players = {}
		end		
		
		local PlayerInfo = {}
		PlayerInfo.Frags = _frags
		PlayerInfo.Deaths = _deaths
		PlayerInfo.Score = _frags - _deaths
		PlayerInfo.Ping = _ping
		PlayerInfo.Name = pl:Nick()
		PlayerInfo.PlayerObj = pl
		
		local insertPos = #TeamInfo[_team].Players + 1
		for idx,info in pairs(TeamInfo[_team].Players) do
			if (PlayerInfo.Frags > info.Frags) then
				insertPos = idx
				break
			elseif (PlayerInfo.Frags == info.Frags) then
				if (PlayerInfo.Deaths < info.Deaths) then
					insertPos = idx
					break
				elseif (PlayerInfo.Deaths == info.Deaths) then
					if (PlayerInfo.Name < info.Name) then
						insertPos = idx
						break
					end
				end
			end
		end
		
		table.insert(TeamInfo[_team].Players, insertPos, PlayerInfo)
	end
	
	return TeamInfo
end

function GM:GetFakeTeamScoreInfo(teamCount, playerCount)
	local TeamInfo = {}
	
	for i = 1, teamCount do
		TeamInfo[i] = {}
		TeamInfo[i].TeamName = "Test Team"
		TeamInfo[i].Color = Color(
			math.max(math.min(i * 20, 255), 0),
			math.max(math.min(255 - i * 25 + 25, 255), 0),
			math.max(math.min(i * 50, 255), 0)
		)
		TeamInfo[i].Players = {}
		
		for j = 1, playerCount do
			local playerInfo = {}
			playerInfo.Frags = 15
			playerInfo.Deaths = 10
			playerInfo.Score = 5
			playerInfo.Ping = 20
			playerInfo.Name = "Test Player"
			playerInfo.PlayerObj = player.GetByID(1)
			
			table.insert(TeamInfo[i].Players, j, playerInfo)
		end
	end
	
	return TeamInfo
end